This code is modified from the original OPUSreader2 documentation vignettes/opusreader2_introduction.Rmd by Philip Baumann and Thomas Knecht. It reads OPUS binary files and extracts metadata and absorbance data, which can then be plotted.
The main function, read_opus(), reads one or more OPUS
files and returns a nested list of class list_opusreader2.
Each list contains both the spectral data and metadata for each file.
The dsn argument is the data source name. It can be a
character vector of folder paths (to read files recursively) or specific
OPUS file paths. Start by testing the read_opus function on your
corrected spectra folder, and saving the output of the first file.
#load opusreader2 from github.com/spectral-cockpit
library(opusreader2)
#save the path to your corrected spectra
# # Mac path
# corr_spectra <- "/Users/adrianneseiden/Library/CloudStorage/Box-Box/Salk Institute Project/AKS Salk files/Adrianne_FTIRdata/Corrected_files" # nolint
# # Windows path
# corr_spectra <- "C:/Users/adria/Box/Box-Box/Salk Institute Project/AKS Salk files/Adrianne_FTIRdata/Corrected_files" # nolint
# # Relative path
# corr_spectra <- "../Adrianne_FTIRdata/Corrected_files"
#save the data from your corrected files as 'data_test'
data_test <- read_opus(dsn = corr_spectra)
#check the names of the list
names(data_test)
> [1] "DRIFTS_pot001_13Cwheat_wk0_root_250725_corr.0"
> [2] "DRIFTS_pot012_13Csoy_wk10_root_250827_corr.0"
> [3] "DRIFTS_pot029_13Cwheat_wk10_root_250827_corr.0"
> [4] "DRIFTS_pot029_13Cwheat_wk40_root_250827_corr.0"
> [5] "DRIFTS_pot030_13Csoy_wk10_root_250725_corr.0"
> [6] "DRIFTS_pot030_13Csoy_wk40_root_250827_corr.0"
> [7] "DRIFTS_pot032_13Cwheat_wk0_root_250725_corr.0"
> [8] "DRIFTS_pot047_13Crice_wk0_root_250725_corr.0"
> [9] "DRIFTS_pot050_13Csoy_wk0_root_250827_corr.0"
> [10] "DRIFTS_pot052_13CnoPlant_wk30_root_250919_corr.0"
> [11] "DRIFTS_pot052_13CnoPlant_wk40_root_250919_corr.0"
> [12] "DRIFTS_pot053_13Cwheat_wk10_root_250725_corr.0"
> [13] "DRIFTS_pot053_13Cwheat_wk40_root_250919_corr.0"
> [14] "DRIFTS_pot055_13Crice_wk10_root_250725_corr.0"
> [15] "DRIFTS_pot055_13Crice_wk40_root_250827_corr.0"
> [16] "DRIFTS_pot055qmark_13Crice_wk10_root_250725_corr.0"
> [17] "DRIFTS_pot056_12Csoy_wk10_root_250919_corr.0"
> [18] "DRIFTS_pot062_13Csoy_wk0_root_250725_corr.0"
> [19] "DRIFTS_pot079_13Crice_wk0_root_250725_corr.0"
> [20] "DRIFTS_pot080_13Csoy_wk10_root_250725_corr.0"
> [21] "DRIFTS_pot080_13Csoy_wk40_root_250919_corr.0"
> [22] "DRIFTS_pot086_12Csoy_wk0_root_250919_corr.0"
> [23] "DRIFTS_pot087_13Crice_wk10_root_250827_corr.0"
> [24] "DRIFTS_pot087_13Crice_wk40_root_250919_corr.0"
> [25] "DRIFTS_pot094_13Csoy_wk10_root_250725_corr.0"
> [26] "DRIFTS_pot094_13Csoy_wk10_soil_250630_corr.0"
> [27] "DRIFTS_pot094_13Csoy_wk40_root_250919_corr.0"
> [28] "DRIFTS_pot103_13Crice_wk0_root_recNMR_250725_corr.0"
> [29] "DRIFTS_pot103_13Crice_wk0_root_vial1_250725_corr.0"
> [30] "DRIFTS_pot103_13Crice_wk0_root_vial2_250725_corr.0"
> [31] "DRIFTS_pot103_13Crice_wk0_root_vial3_250725_corr.0"
> [32] "DRIFTS_pot107_12Crice_wk0_root_really13_250725_corr.0"
> [33] "DRIFTS_pot109_13Cwheat_wk40_root_250919_corr.0"
> [34] "DRIFTS_pot119_13Crice_wk10_root_250827_corr.0"
> [35] "DRIFTS_pot119_13Crice_wk40_root_250919_corr.0"
# define 'meas_1' as the first element of the 'data_test' list
meas_1 <- data_test[[1]]Next I defined a function, plotSpectrum, to plot the spectral data from a single sample (meas_1)
# data is a list containing OPUS file data, including absorbance and metadata.
plotSpectrum <- function(data) { # nolint: object_name_linter.
ab_data <- data$ab
if (!is.null(ab_data) &&
!is.null(ab_data$wavenumbers) && !is.null(ab_data$data) &&
is.numeric(ab_data$wavenumbers) && is.numeric(ab_data$data) &&
length(ab_data$wavenumbers) == length(ab_data$data) &&
all(is.finite(ab_data$wavenumbers)) && all(is.finite(ab_data$data))) {
plot(
ab_data$wavenumbers, ab_data$data, type = "l",
xlab = "Wavenumber (cm⁻¹)", ylab = "Absorbance",
main = data$basic_metadata$dsn_filename,
xlim = rev(range(ab_data$wavenumbers))
)
} else {
cat("Absorbance data not found or not valid in this file.\n")
str(ab_data)
}
}
plotSpectrum(meas_1)I then defined the metadataTable function, to extract and display the a subset of the metadata stored in the data extracted by ‘read_opus’ in a table format.
To view all the available data categories, run ‘names(meas_1)’ in the console. To view the parameters within these categories use str(meas_1$category_name) where ‘category_name’ is ‘basic_metadata’, ‘optics’, etc.
The plotMetadata function combines the plot and table for a single spectrum.
plotMetadata <- function(data) { # nolint: object_name_linter.
plotSpectrum(data)
metadataTable(data)
}
plotMetadata(meas_1)| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot001_13Cwheat_wk0_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:18:39 GMT-7 |
| Max Y | 0.799607157707214 |
| Min Y | -0.0012896629050374 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56884765625 |
| Experiment (method) | SALK_soils_method.xpm |
The following for loop runs plotMetadata on each spectrum in the data_test list, which contains all the spectra in the folder. It will plot each spectrum and print its metadata below.
for (i in seq_along(data_test)) {
cat("#### Spectrum", i, ":", names(data_test)[i], "\n\n")
data_i <- data_test[[i]]
ab_data <- data_i$ab
valid <- !is.null(ab_data) &&
!is.null(ab_data$wavenumbers) && !is.null(ab_data$data) &&
is.numeric(ab_data$wavenumbers) && is.numeric(ab_data$data) &&
length(ab_data$wavenumbers) == length(ab_data$data) &&
all(is.finite(ab_data$wavenumbers)) && all(is.finite(ab_data$data))
if (valid) {
plotSpectrum(data_i)
print(metadataTable(data_i))
} else {
cat("Data not valid or missing for this spectrum.\n")
str(ab_data)
}
}| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot001_13Cwheat_wk0_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:18:39 GMT-7 |
| Max Y | 0.799607157707214 |
| Min Y | -0.0012896629050374 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56884765625 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot012_13Csoy_wk10_root_250827_corr.0 |
| Timestamp | 2025-08-27 18:52:52 GMT-7 |
| Max Y | 0.797225415706635 |
| Min Y | -0.00604866677895188 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.560791015625 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot029_13Cwheat_wk10_root_250827_corr.0 |
| Timestamp | 2025-08-27 18:53:45 GMT-7 |
| Max Y | 0.722125887870789 |
| Min Y | -0.00508248526602983 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.559814453125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot029_13Cwheat_wk40_root_250827_corr.0 |
| Timestamp | 2025-08-27 18:54:46 GMT-7 |
| Max Y | 0.828895390033722 |
| Min Y | -0.00468211621046066 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.560791015625 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot030_13Csoy_wk10_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:21:37 GMT-7 |
| Max Y | 0.84355878829956 |
| Min Y | -0.00326710939407349 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56689453125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot030_13Csoy_wk40_root_250827_corr.0 |
| Timestamp | 2025-08-27 18:54:58 GMT-7 |
| Max Y | 0.721331775188446 |
| Min Y | -0.00639449199661613 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.559814453125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot032_13Cwheat_wk0_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:22:45 GMT-7 |
| Max Y | 0.909599244594574 |
| Min Y | -0.00415003532543778 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56982421875 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot047_13Crice_wk0_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:23:56 GMT-7 |
| Max Y | 0.712926685810089 |
| Min Y | -0.00133463030215353 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56591796875 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot050_13Csoy_wk0_root_250827_corr.0 |
| Timestamp | 2025-08-27 18:55:10 GMT-7 |
| Max Y | 0.772085309028625 |
| Min Y | -0.00875790882855654 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.560791015625 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot052_13CnoPlant_wk30_root_250919_corr.0 |
| Timestamp | 2025-09-19 18:16:15 GMT-7 |
| Max Y | 0.77551531791687 |
| Min Y | -0.005828230176121 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.392822265625 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot052_13CnoPlant_wk40_root_250919_corr.0 |
| Timestamp | 2025-09-19 18:16:20 GMT-7 |
| Max Y | 0.813514113426208 |
| Min Y | -0.004625812638551 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.393798828125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot053_13Cwheat_wk10_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:24:39 GMT-7 |
| Max Y | 0.997280716896057 |
| Min Y | -0.00962971057742834 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56591796875 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot053_13Cwheat_wk40_root_250919_corr.0 |
| Timestamp | 2025-09-19 15:59:23 GMT-7 |
| Max Y | 0.797653913497925 |
| Min Y | -0.00369235360994935 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.389892578125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot055_13Crice_wk10_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:26:35 GMT-7 |
| Max Y | 0.816974341869354 |
| Min Y | -0.00123318459372967 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56689453125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot055_13Crice_wk40_root_250827_corr.0 |
| Timestamp | 2025-08-27 18:55:22 GMT-7 |
| Max Y | 0.852853655815125 |
| Min Y | -0.00635257223621011 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56396484375 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot055qmark_13Crice_wk10_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:25:51 GMT-7 |
| Max Y | 0.907369911670685 |
| Min Y | -0.00234174402430654 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56591796875 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot056_12Csoy_wk10_root_250919_corr.0 |
| Timestamp | 2025-10-07 18:03:40 GMT-7 |
| Max Y | 0.615259230136871 |
| Min Y | -0.0116841280832887 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.393798828125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot062_13Csoy_wk0_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:27:28 GMT-7 |
| Max Y | 0.687717080116272 |
| Min Y | -0.00538174575194716 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56884765625 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot079_13Crice_wk0_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:28:00 GMT-7 |
| Max Y | 0.816869914531708 |
| Min Y | -0.00257659493945539 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56787109375 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot080_13Csoy_wk10_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:28:56 GMT-7 |
| Max Y | 0.77625048160553 |
| Min Y | -0.00814440380781889 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56689453125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot080_13Csoy_wk40_root_250919_corr.0 |
| Timestamp | 2025-09-19 16:42:23 GMT-7 |
| Max Y | 0.764196336269379 |
| Min Y | -0.00511131621897221 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.391845703125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot086_12Csoy_wk0_root_250919_corr.0 |
| Timestamp | 2025-10-07 18:04:00 GMT-7 |
| Max Y | 0.540434181690216 |
| Min Y | -0.0042975265532732 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.386962890625 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot087_13Crice_wk10_root_250827_corr.0 |
| Timestamp | 2025-08-27 18:55:34 GMT-7 |
| Max Y | 0.699629366397858 |
| Min Y | -0.00116329535376281 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.560791015625 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot087_13Crice_wk40_root_250919_corr.0 |
| Timestamp | 2025-09-19 17:31:48 GMT-7 |
| Max Y | 0.879431128501892 |
| Min Y | -0.0040658856742084 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.392822265625 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot094_13Csoy_wk10_root_250725_corr.0 |
| Timestamp | 2025-07-25 20:29:09 GMT-7 |
| Max Y | 1.27848649024963 |
| Min Y | -0.00875786785036325 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56689453125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot094_13Csoy_wk10_soil_250630_corr.0 |
| Timestamp | 2025-07-25 20:46:03 GMT-7 |
| Max Y | 0.821687042713165 |
| Min Y | -0.00153941253665835 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.454833984375 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot094_13Csoy_wk40_root_250919_corr.0 |
| Timestamp | 2025-09-19 16:42:30 GMT-7 |
| Max Y | 0.825236082077026 |
| Min Y | -0.00458295457065105 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.391845703125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot103_13Crice_wk0_root_recNMR_250725_corr.0 |
| Timestamp | 2025-07-25 20:30:32 GMT-7 |
| Max Y | 0.836920917034149 |
| Min Y | -0.00138377456460148 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56982421875 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot103_13Crice_wk0_root_vial1_250725_corr.0 |
| Timestamp | 2025-07-25 20:30:55 GMT-7 |
| Max Y | 0.826825261116028 |
| Min Y | -0.000596170837525278 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56787109375 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot103_13Crice_wk0_root_vial2_250725_corr.0 |
| Timestamp | 2025-07-25 20:31:26 GMT-7 |
| Max Y | 0.984898567199707 |
| Min Y | -0.00565983727574348 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56591796875 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot103_13Crice_wk0_root_vial3_250725_corr.0 |
| Timestamp | 2025-07-25 20:31:46 GMT-7 |
| Max Y | 0.983739078044891 |
| Min Y | -0.0026757272426039 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56591796875 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot107_12Crice_wk0_root_really13_250725_corr.0 |
| Timestamp | 2025-07-25 20:32:00 GMT-7 |
| Max Y | 1.03206670284271 |
| Min Y | -0.00172662467230111 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.56591796875 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot109_13Cwheat_wk40_root_250919_corr.0 |
| Timestamp | 2025-09-19 15:59:28 GMT-7 |
| Max Y | 0.75251305103302 |
| Min Y | -0.00450036907568574 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.386962890625 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot119_13Crice_wk10_root_250827_corr.0 |
| Timestamp | 2025-08-27 18:55:49 GMT-7 |
| Max Y | 0.808935940265656 |
| Min Y | -0.0116460844874382 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.561767578125 |
| Experiment (method) | SALK_soils_method.xpm |
| Parameter | Value |
|---|---|
| File Name | DRIFTS_pot119_13Crice_wk40_root_250919_corr.0 |
| Timestamp | 2025-09-19 17:31:43 GMT-7 |
| Max Y | 0.954932034015656 |
| Min Y | -0.00412484398111701 |
| Aperture Setting | 6 mm |
| Scanner Velocity | 10.0S |
| Result Spectrum | AB |
| Resolution | 4 |
| Sample Scans | 400 |
| End Frequency | 400 |
| Start Frequency | 4000 |
| Duration | 364.390869140625 |
| Experiment (method) | SALK_soils_method.xpm |
This code looks for files with the same sample number and stacks their spectra, to check whether reruns are consistent.
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
echo = TRUE,
results = "markup",
include = TRUE
)
library(opusreader2)
library(RColorBrewer)
data_test <- read_opus(dsn = corr_spectra)
# Helper to extract sample number from filename (e.g., "pot094")
extract_sample_number <- function(filename) {
m <- regexpr("[a-z]{3}[0-9]+", filename)
if (m[1] != -1) {
regmatches(filename, m)
} else {
NA
}
}
# Helper to extract sample type (e.g.,"soil", "root")
extract_sample_type <- function(filename) {
m <- regexpr("soil|root", filename, ignore.case = TRUE)
if (m[1] != -1) {
tolower(regmatches(filename, m))
} else {
NA
}
}
# Helper to extract timepoint (e.g., "wk0", "wk40")
extract_timepoint <- function(filename) {
m <- regexpr("wk[0-9]+", filename, ignore.case = TRUE)
if (m[1] != -1) {
tolower(regmatches(filename, m))
} else {
NA
}
}
# Group files by sample number, sample type, and timepoint
sample_numbers <- sapply(names(data_test), extract_sample_number)
sample_types <- sapply(names(data_test), extract_sample_type)
timepoints <- sapply(names(data_test), extract_timepoint)
# Create unique combinations of sample number, sample type, and timepoint
sample_combinations <- paste(sample_numbers, sample_types, timepoints, sep = "_")
unique_combinations <- unique(sample_combinations[!is.na(sample_numbers)
& !is.na(sample_types)
& !is.na(timepoints)])
# Plot stacked spectra for each unique combination
library(RColorBrewer)
for (combination in unique_combinations) {
idx <- which(sample_combinations == combination)
if (length(idx) > 1) {
# Extract sample number, type, and timepoint from combination
parts <- strsplit(combination, "_")[[1]]
sample_num <- parts[1]
sample_type <- parts[2]
timepoint <- parts[3]
spectra <- data_test[idx]
colors <- brewer.pal(min(length(spectra), 8), "Set1")
plot(NULL, xlim = rev(range(spectra[[1]]$ab$wavenumbers)),
ylim = range(sapply(spectra, function(x) x$ab$data), na.rm = TRUE),
xlab = "Wavenumber (cm⁻¹)", ylab = "Absorbance",
main = paste("Stacked spectra for", sample_num, "-", sample_type, "-", timepoint),
bty = "l")
for (i in seq_along(spectra)) {
ab_data <- spectra[[i]]$ab
if (!is.null(ab_data) && !is.null(ab_data$wavenumbers) &&
!is.null(ab_data$data)) {
lines(ab_data$wavenumbers, ab_data$data, col = colors[i], lwd = 2)
}
}
legend("topright",
inset = c(-0.05, -0.02),
legend = names(spectra),
col = colors[seq_along(spectra)],
lwd = 2,
xpd = TRUE,
bty = "n")
}
}This code stacks spectra of the same crop and timepoint.
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
echo = TRUE,
results = "markup",
include = TRUE
)
# Helper functions to extract crop and timepoint from filename
extract_crop <- function(filename) {
m <- regexpr("rice|wheat|soy", filename, ignore.case = TRUE)
if (m[1] != -1) tolower(regmatches(filename, m)) else NA
}
extract_time <- function(filename) {
m <- regexpr("wk[0-9]+", filename, ignore.case = TRUE)
if (m[1] != -1) tolower(regmatches(filename, m)) else NA
}
extract_sample_type <- function(filename) {
m <- regexpr("root|soil", filename, ignore.case = TRUE)
if (m[1] != -1) {
tolower(regmatches(filename, m))
} else {
NA
}
}
# Get crop and time for each file
crops <- sapply(names(data_test), extract_crop)
times <- sapply(names(data_test), extract_time)
types <- sapply(names(data_test), extract_sample_type)
# Unique crop-time combinations
combos <- na.omit(unique(paste(crops, times, types, sep = "_")))
library(RColorBrewer)
for (combo in combos) {
idx <- which(paste(crops, times, types, sep = "_") == combo)
if (length(idx) > 1) {
spectra <- data_test[idx]
colors <- brewer.pal(min(length(spectra), 8), "Set1")
plot(NULL, xlim = rev(range(spectra[[1]]$ab$wavenumbers)),
ylim = range(sapply(spectra, function(x) x$ab$data), na.rm = TRUE),
xlab = "Wavenumber (cm⁻¹)", ylab = "Absorbance",
main = paste("Stacked spectra for", combo),
bty = "l")
for (i in seq_along(spectra)) {
ab_data <- spectra[[i]]$ab
if (!is.null(ab_data) &&
!is.null(ab_data$wavenumbers)
&& !is.null(ab_data$data)) {
lines(ab_data$wavenumbers, ab_data$data, col = colors[i], lwd = 2)
}
}
legend("topright",
inset = c(-0.05, -0.02),
legend = names(spectra),
col = colors[seq_along(spectra)],
lwd = 2,
xpd = TRUE,
bty = "n")
}
}